package com.smileus.util;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.oro.text.regex.MatchResult;
import org.apache.oro.text.regex.Pattern;
import org.apache.oro.text.regex.PatternCompiler;
import org.apache.oro.text.regex.PatternMatcherInput;
import org.apache.oro.text.regex.Perl5Compiler;
import org.apache.oro.text.regex.Perl5Matcher;

/**
 * @author : dongheng
 * @date : 2009-7-17 上午08:42:31
 * @hestory :
 * @description :
 */
public class StringUtil {
	public static final String NULL_CONTENT = "";
	private static final String REG_STRING = "\\s+\\S+\\s*(=\\s*:|<\\s*:|<=\\s*:|>\\s*:|>=\\s*:|!=\\s*:|like\\s*:)\\s*\\S+\\s*";
	public static String processRegExp(String inputValue, String reg) {
		PatternCompiler compile = new Perl5Compiler();
		try {
			Pattern pattern = compile.compile(reg, Perl5Compiler.CASE_INSENSITIVE_MASK);
			PatternMatcherInput input = new PatternMatcherInput(inputValue);
			Perl5Matcher matcher = new Perl5Matcher();
			MatchResult result = null;
			int i = 0;
			while (matcher.contains(input, pattern)) {
				result = matcher.getMatch();
				System.out.println("result =" + result.group(0));
				String replaced = matcher.getMatch().group(0);
				inputValue = inputValue.replace(replaced, " 1=1 ");
				System.out.println("replaced =" + replaced + " and result = " + inputValue);
				input.setBeginOffset(result.length());
				i++;
			}
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}
		return inputValue;
	}

	/**
	 * "from UnallocatedVisitBillResult where agentVisitTime>=:beginVisitTime
	 * and agentVisitTime<=:endVisitTime and companyName=:companyName and
	 * 返回所有匹配 p.name =:name 模式结果 , String reg = "\\s+\\S+\\s*(=\\s*:|<\\s*:|<=\\s*:|>\\s*:|>=\\s*:|!=\\s*:|like\\s*:)\\s*\\S+\\s*";
	 * 
	 * @param inputValue
	 * @return
	 */
	public static Map<String, Object> processMapHQL(String inputValue, Map<String, Object> param) {
		Map<String, Object> map = new HashMap<String, Object>();
		Set<String> keySet = new HashSet<String>();
		String result = null;
		String key = null;
		Object value = null;
		PatternCompiler compile = new Perl5Compiler();
		List<Object> paramList = new ArrayList<Object>();
		try {
			Pattern pattern = compile.compile(REG_STRING, Perl5Compiler.CASE_INSENSITIVE_MASK);
			PatternMatcherInput input = new PatternMatcherInput(inputValue);
			Perl5Matcher matcher = new Perl5Matcher();
			while (matcher.contains(input, pattern)) {
				result = matcher.getMatch().group(0);
				key = getKey(result);
				value = param.get(key);
				keySet.add(key);
				if (param.containsKey(key) == false || value == null || NULL_CONTENT.equals(value)) {
					inputValue = inputValue.replace(result, " 1=1 ");
				} else {
					paramList.add(value);
				}
				input.setBeginOffset(result.length());
			}
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}
		inputValue = inputValue.replace("and 1=1", "");
		map.put("paramList", paramList);
		map.put("hql", inputValue);
		map.put("keySet", keySet);
		return map;
	}

	/**
	 * "from UnallocatedVisitBillResult where agentVisitTime>=:beginVisitTime
	 * and agentVisitTime<=:endVisitTime and companyName=:companyName and
	 * 返回所有匹配 p.name =:name 模式结果 , String reg = "\\s+\\S+\\s*(=\\s*:|<\\s*:|<=\\s*:|>\\s*:|>=\\s*:|!=\\s*:|like\\s*:)\\s*\\S+\\s*";
	 * 
	 * @param inputValue
	 * @return
	 */
	public static Map<String, Object> processValueBeanHQL(String inputValue, Map<String, Field> param, Object valueBean) {
//		String reg = "\\s+\\S+\\s*(=\\s*:|<\\s*:|<=\\s*:|>\\s*:|>=\\s*:|!=\\s*:|like\\s*:)\\s*\\S+\\s*";
		PatternCompiler compile = new Perl5Compiler();
		Map<String, Object> map = new HashMap<String, Object>();
		Set<String> keySet = new HashSet<String>();
		List<Object> paramList = new ArrayList<Object>();
		String result = null;
		String key = null;
		Object value = null;
		try {
			Pattern pattern = compile.compile(REG_STRING, Perl5Compiler.CASE_INSENSITIVE_MASK);
			PatternMatcherInput input = new PatternMatcherInput(inputValue);
			Perl5Matcher matcher = new Perl5Matcher();
			// 处理hql
			while (matcher.contains(input, pattern)) {
				result = matcher.getMatch().group(0);
				key = getKey(result);
				keySet.add(key);
				if (param.containsKey(key) == false) {
					inputValue = inputValue.replace(result, " 1=1 ");
				} else {
					value = param.get(key).get(valueBean);
					if (value == null || NULL_CONTENT.equals(value)) {
						inputValue = inputValue.replace(result, " 1=1 ");
					} else {
						paramList.add(value);
					}
				}
				input.setBeginOffset(result.length());
			}

			// 处理Map中冗余的参数
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}

		inputValue = inputValue.replace("and 1=1", "");
		map.put("paramList", paramList);
		map.put("hql", inputValue);
		map.put("keySet", keySet);
		return map;
	}

	public static List<String> getPatternList(String inputValue) {
		List<String> list = new ArrayList<String>();
		String[] array = inputValue.split("}");
		String reg = "\\{:\\S+";
		PatternCompiler compile = new Perl5Compiler();
		try {
			Pattern pattern = compile.compile(reg, Perl5Compiler.CASE_INSENSITIVE_MASK);
			for (String curtStr : array) {
				PatternMatcherInput input = new PatternMatcherInput(curtStr);
				Perl5Matcher matcher = new Perl5Matcher();
				MatchResult result = null;
				int i = 0;
				while (matcher.contains(input, pattern)) {
					result = matcher.getMatch();
					String replaced = result.group(0).split(":")[1];
					list.add(replaced);
					System.out.println("result =" + replaced);
					input.setBeginOffset(result.length());
					i++;
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}
		return list;
	}

	public static String getKey(String result) {
		String[] array = result.split(":");
		return array[array.length - 1].trim();
	}
}
